<template>
  <!--通用列表页-->
  <div class="common-table">

    <!--查询-->
    <div v-if="showFilterContainer" class="filter-container">
      <!--查询表单-->
      <el-form ref="qo" :inline="true" :model="qo">
        <slot name="filterItems" />
      </el-form>
      <!--查询框按钮-->
      <div class="filter-button-container">
        <el-button type="primary" icon="el-icon-search" @click="search">
          搜索
        </el-button>
        <el-button icon="el-icon-refresh" @click="refreshQo">
          重置
        </el-button>
      </div>
    </div>

    <!--顶部按钮-->
    <TopButton :baba="baba" :up="this" :buttons="topButtons" :show-config="topButtonShowConfig" />

    <!--列表-->
    <el-table ref="table" v-loading="showLoading" :data="data" highlight-current-row class="table-container" @row-click="handleRowClick">
      <slot name="column" />
      <!-- 右侧单列按钮 -->
      <el-table-column v-if="singleRowButtons && singleRowButtons.length > 0" label="操作" width="105px">
        <template slot-scope="scope">
          <SingleRowButton :baba="baba" :row="scope.row" :buttons="singleRowButtons" />
        </template>
      </el-table-column>
    </el-table>

    <!--分页-->
    <Pagination :total="total" :page.sync="page" :limit.sync="size" @pagination="listData" />
  </div>
</template>

<script>
import Pagination from '@/components/Pagination'
import TopButton from '@/components/TopButton'
import SingleRowButton from '@/components/SingleRowButton'
import { getDictSelectData, getIdArray } from '@/utils/common'
import { batchGetEntityFileCount } from '@/api/system/file'
export default {
  name: 'CommonTable',
  components: { Pagination, TopButton, SingleRowButton },
  props: {
    baba: {
      type: Object,
      required: true
    },
    // 查询参数对象
    qo: {
      type: Object,
      required: true
    },
    // 查询方法名称
    getDataFun: {
      type: String,
      default: 'getData'
    },
    // 同一页面存在多个table 时需要此值,详见 dict页
    singleRowButtonPosition: {
      type: String,
      default: 'ROW'
    },
    // 同一页面存在多个table 时需要此值,详见 dict页
    topButtonPosition: {
      type: String,
      default: 'TOP'
    },
    /**
     * 顶部按钮显示配置
     * left 显示左侧全部按钮
     * right 是否显示右侧按钮
     * filter 显示右侧示过滤容器按钮
     * refresh 显示右侧刷新列表按钮
     * colCheck 显示右侧选择列表显示字典按钮
     */
    topButtonShowConfig: {
      type: String,
      default: 'left, right, filter, refresh'
    },
    // 需要加载的字典, 形如 ['system_faq_type']
    needLoadDictType: {
      type: Array,
      default: _ => []
    },
    // 需要异步加载列表数据关联的附件
    asyncLoadEntityFileCount: {
      type: Boolean,
      required: false
    },
    // 单击列表单行事件
    rowClick: {
      type: Function,
      default: row => {}
    }
  },
  data() {
    return {
      showLoading: false, data: null, total: 0, page: 1, size: 10, currentRow: undefined,
      singleRowButtons: undefined, showFilterContainer: true, topButtons: undefined
    }
  },
  created() {
    this.getSingleRowButtons()
    this.getTopButtons()
    this.batchLoadDict().then(() => { this.listData() })
  },
  methods: {
    // 查询数据列表
    listData() {
      this.showLoading = true
      this.qo.page = this.page
      this.qo.size = this.size
      setTimeout(() => {
        this.baba[this.getDataFun](this.qo).then(res => {
          this.data = res.rows
          this.total = res.total
          this.showLoading = false
          if (this.asyncLoadEntityFileCount) {
            this.asyncGetEntityFileCount()
          }
        }).catch(() => {
          this.showLoading = false
        })
      }, 400)
    },
    // 刷新列表
    search() {
      this.page = 1
      this.listData()
    },
    refreshQo() {
      this.$refs.qo.resetFields()
    },
    // 获取单行数据的操作按钮
    getSingleRowButtons() {
      this.singleRowButtons = this.getButtons(this.singleRowButtonPosition)
    },
    // 获取列表顶部按钮
    getTopButtons() {
      this.topButtons = this.getButtons(this.topButtonPosition)
    },
    getButtons(position) {
      const metaButtons = this.$route.meta.buttons
      return metaButtons !== null && metaButtons !== undefined ? metaButtons[position] : []
    },
    // 批量加载字典
    batchLoadDict() {
      return new Promise(resolve => {
        if (this.needLoadDictType && this.needLoadDictType.length > 0) {
          this.needLoadDictType.forEach(dictType => {
            getDictSelectData(dictType)
          })
        }
        resolve()
      })
    },
    // 切换过滤表单显示/隐藏
    switchShowFilterContainer() {
      this.showFilterContainer = !this.showFilterContainer
    },
    // 获取多选数据行所有ID
    getSelectedRowIds() {
      return new Promise((resolve, reject) => {
        const rows = this.$refs.table.selection
        if (rows && rows.length > 0) {
          const ids = getIdArray(rows)
          resolve(ids)
        } else {
          this.$message.warning('请选中至少一条')
        }
      })
    },
    // 获取多选数据行所有数据
    getSelectedRows() {
      return new Promise((resolve, reject) => {
        const rows = this.$refs.table.selection
        if (rows && rows.length > 0) {
          resolve(rows)
        } else {
          this.$message.warning('请选中至少一条')
        }
      })
    },
    // 获取当前行
    getCurrentRow() {
      return new Promise((resolve, reject) => {
        if (this.currentRow) {
          resolve(this.currentRow)
        } else {
          this.$message.warning('请选中一条记录')
        }
      })
    },
    // 异步批量获取单据附件数量
    asyncGetEntityFileCount() {
      const data = this.data
      if (data && data.length > 0) {
        const entityIds = getIdArray(data)
        batchGetEntityFileCount(entityIds).then(res => {
          data.forEach((item, index) => {
            item.fileCount = res[index]
          })
        })
      }
    },
    // 单行被点击时触发
    handleRowClick(row) {
      this.currentRow = row
      // 回传选中行数据 并返回根节点方便其他操作
      this.rowClick(row)
    }
  }
}
</script>
